#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include "log.hpp"
using namespace mylog;
struct sockaddr_in server;
int sockfd;

void *send(void *argv)
{
    while (true)
    {
        // 发送信息
        std::string massage;
        std::getline(std::cin, massage);
        ssize_t n = sendto(sockfd, massage.c_str(), massage.size(), 0, (struct sockaddr *)&server, sizeof(server));
        if (n < 0)
        {
            std::cerr << "sendto error" << std::endl;
        }
        if (massage == "QUIT")
            break;
    }
    return nullptr;
}

void *recv(void *argv)
{
    while (true)
    {
        struct sockaddr_in peer;
        socklen_t len;
        char buff[256];
        ssize_t m = recvfrom(sockfd, buff, sizeof(buff) - 1, 0, (struct sockaddr *)&peer, &len);
        if (m < 0)
        {
            std::cerr << "recvfrom error" << std::endl;
        }
        buff[m] = 0;
        std::cerr << buff << std::endl;
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "usage : ./udpclient server_ip server_port" << std::endl;
        exit(1);
    }
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(argv[1]);
    server.sin_port = htons(std::stoi(argv[2]));
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        LOG(Level::FATAL) << "socket error";
        exit(1);
    }
    LOG(Level::INFO) << "socket success, _sockfd : " << sockfd;
    // client无需显示绑定，首次发送信息时，OS自动绑定

    // 创建线程
    pthread_t sd, rv;
    pthread_create(&sd, nullptr, send, nullptr);
    pthread_create(&rv, nullptr, recv, nullptr);

    pthread_join(sd, nullptr);

    pthread_cancel(rv);
    pthread_join(rv, nullptr);
    
    return 0;
}